/**
 * 常用的一些工具方法
 */
var QuickTuiUtils = {
	exname: "quicktui",
	exhost: "chrome://quicktui",
	
	CHARS: "0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz",
	
	prefs: Components.classes['@mozilla.org/preferences-service;1']
	           		.getService(Components.interfaces.nsIPrefService)
					.getBranch("extensions.quicktui."),
	
	$: function(id) {
	    return document.getElementById(id);
	},

	log: function(aText) {

	    if (this.prefs.getBoolPref("debug")) {
	        if (this._console == null) {
	            this._console = Components.classes["@mozilla.org/consoleservice;1"]
	            .getService(Components.interfaces.nsIConsoleService);
	        }
	        this._console.logStringMessage(aText);
	        dump(aText + "n");
	    }
	},
	
	initXMLHttpRequest: function() {
		var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"]
					.createInstance(Components.interfaces.nsIXMLHttpRequest);
		req.mozBackgroundRequest = true; // FUCK, 如果没有这个，就会弹出个窗口让你输入用户名密码验证
		return req;
	},
	
	msg: {
		popup: function(imageUrl, title, text) {
			try {  
			    Components.classes['@mozilla.org/alerts-service;1']  
			              .getService(Components.interfaces.nsIAlertsService)  
			              .showAlertNotification(imageUrl, title, text, false, '', null)  
			} catch(e) {  
			  	// prevents runtime error on platforms that don't implement nsIAlertsService  
				this.alert(text);
			}
		},
		
		alert: function(imageUrl, title, text) {
		  	var win = Components.classes['@mozilla.org/embedcomp/window-watcher;1']
		                      .getService(Components.interfaces.nsIWindowWatcher)
		                      .openWindow(null, 'chrome://global/content/alerts/alert.xul',
		                                  '_blank', 'chrome,titlebar=no,popup=yes', null)
		  	win.arguments = [imageUrl, title, text, false, '']
		},
		
		showInfoNotification: function(notificationbox, label, image) {
			this.showNotification(notificationbox, label, image, notificationbox.PRIORITY_INFO_MEDIUM);
		},
		
		showWarnNotification: function(notificationbox, label, image) {
			this.showNotification(notificationbox, label, image, notificationbox.PRIORITY_WARNING_MEDIUM);
		},
		
		showErrorNotification: function(notificationbox, label, image) {
			this.showNotification(notificationbox, label, image, notificationbox.PRIORITY_CRITICAL_HIGH);
		},
		
		showNotification: function(notificationbox, label, image, priority, buttons) {
			notificationbox.appendNotification(label, label, image, priority, buttons);
			var scope = this;
			
			var event = {
				notify: function(timer) {
					scope.hideNotification(notificationbox);
				}
			};
			
			var timer = Components.classes["@mozilla.org/timer;1"]
			                    .createInstance(Components.interfaces.nsITimer);
			timer.initWithCallback(
							   event,
							   3000,
							   Components.interfaces.nsITimer.TYPE_ONE_SHOT);
			
		},
		
		hideNotification: function(notificationbox) {
			notificationbox.removeCurrentNotification();
			// notificationbox.removeAllNotifications(false);
		}
	},
	
	trim: function(s) {
		return s.replace(/^\s+/, '').replace(/\s+$/, '');
	},
	
	ellipsis: function(value, len){
        if(value && value.length > len){
            return value.substr(0, len-3) + "...";
        }
        return value;
    },

	win: {
		location: function(win) {
			return win.content.location.href;
		},
		title: function(win) {
			return win.content.document.title;
		},
		selection: function(win) {
			return win.content.getSelection().toString();
		}
	},

	toUTF8Octets: function(string) {
	    return unescape(encodeURIComponent(string));
	},

	btoa: function(input) {
	    var keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";

	    var output = "";
	    var chr1, chr2, chr3;
	    var enc1, enc2, enc3, enc4;
	    var i = 0;

	    do {
	        chr1 = input.charCodeAt(i++);
	        chr2 = input.charCodeAt(i++);
	        chr3 = input.charCodeAt(i++);

	        enc1 = chr1 >> 2;
	        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
	        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
	        enc4 = chr3 & 63;

	        if (isNaN(chr2)) {
	            enc3 = enc4 = 64;
	        } else if (isNaN(chr3)) {
	            enc4 = 64;
	        }

	        output = output + keyStr.charAt(enc1) + keyStr.charAt(enc2) +
	        keyStr.charAt(enc3) + keyStr.charAt(enc4);
	    }
	    while (i < input.length);

	    return output;
	},
	
	nonce: function(length) {
        var chars = this.CHARS;
        var result = "";
        for (var i = 0; i < length; ++i) {
            var rnum = Math.floor(Math.random() * chars.length);
            result += chars.substring(rnum, rnum+1);
        }
        return result;
    }
};